﻿using App.Cache;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Simple.BasicNet.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;

namespace App
{
    public class VersionUpgradeHanlder
    {
		private readonly IRedisClientService cache;
		private ILogger logger;
		private HttpClient httpClient;

		public VersionUpgradeHanlder(IRedisClientService cache, ILogger logger,IDTConfiguration configuration)
		{
			this.cache = cache;
			this.httpClient = new HttpClient();
			httpClient.BaseAddress = new Uri(configuration.ApiAddress);//http://172.16.1.128:7125"
			this.logger = logger;	
		}
		public bool CheckResult { get; private set; } = false;

		public UpFileInfo _UpFileInfo { get; private set; }

		public async Task CheckVersion(string SerialNumber, int clientType, string wareVersion = "")
		{
			CheckResult = false;
			//var httpClient = httpClientFactory.CreateClient("upgrade");

			var request = new HttpRequestMessage(
			   HttpMethod.Post,
			   $"api/signalr/dtm/version/lastest?SerialNumber={SerialNumber}&clientType={clientType}&cur_version={wareVersion}"
			   );

			// var post = new { clientType = clientType, cur_version = wareVersion };
			// var str = string.Format("appid=6271f194&clientType={0}&cur_version={1}", post.clientType, post.cur_version);

			//if (request.Content == null)
			//{
			//    CheckResult = false;
			//    Log.Error($"获取版本信息失败：null");

			//}
			//else
			//{
			request.Headers.Add("ContentType", "application/x-www-form-urlencoded");
			//request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
			var response = await httpClient.SendAsync(request);
			if (response.IsSuccessStatusCode)
			{
				var responseStream = await response.Content.ReadAsStringAsync();
				var data = JsonConvert.DeserializeObject<JObject>(responseStream);
				logger.Info(responseStream);
				if (int.Parse(data["code"].ToString()) == 200)
				{
					CheckResult = true;

					await cache.SetAsync($"productversionid:{SerialNumber}", data["data"]["productVersionId"].ToString(), 0);
					await WriteVersionAsync(clientType, data["data"]["productVersionId"].ToString(), JsonConvert.SerializeObject(data["data"]));
				}
				else
				{
					CheckResult = false;
				}
			}
			else
			{
				CheckResult = false;
				logger.Info($"获取版本信息失败：{response.StatusCode}");
			}
		}

		public async Task<bool> SetFileCacheAsync(int clientType, string version, int maxSingleSize, string productVersionId)
		{
			var vu = await GetVersionAsync(clientType, productVersionId);

			if (vu == null)
			{
				_UpFileInfo = new UpFileInfo() { PackNum = 0, Size = 0, Version = "null" };
				return false;

			}
			var upfile = $"/{vu.FileUrl.Substring(vu.FileUrl.LastIndexOf("/") + 1)}";
			logger.Info(vu.FileUrl);
			//HttpClient client = httpClientFactory.CreateClient();
			HttpResponseMessage response = await httpClient.GetAsync(upfile);
			using var stream = await response.Content.ReadAsStreamAsync();
			if (stream.Length == 0)
			{
				logger.Info("更新包长度为0");
				_UpFileInfo = new UpFileInfo() { PackNum = 0, Size = 0, Version = vu.VersionCode };
				return false;
			}
			byte[] upbytes = new byte[stream.Length];
			await stream.ReadAsync(upbytes, 0, upbytes.Length);

			// 设置当前流的位置为流的开始 
			stream.Seek(0, SeekOrigin.Begin);

			//if (!File.Exists(upfile))
			//{
			//    return;
			//}



			await cache.DelAsync($"upgrade:{vu.VersionCode}:{productVersionId}:{clientType}");


			//var upbytes = await File.ReadAllBytesAsync(upfile);
			var lastPackLength = upbytes.Length % maxSingleSize;

			var PackCount = upbytes.Length / maxSingleSize + (lastPackLength > 0 ? 1 : 0);
			var tempBytes = new byte[maxSingleSize];
			for (int i = 0; i < PackCount; i++)
			{
				if (i == PackCount - 1)
				{
					tempBytes = new byte[lastPackLength];
					Array.Copy(upbytes, i * maxSingleSize, tempBytes, 0, lastPackLength);
				}
				else
				{
					Array.Copy(upbytes, i * maxSingleSize, tempBytes, 0, maxSingleSize);
				}
				cache.RPushAsync($"upgrade:{vu.VersionCode}:{vu.ProductVersionId}:{clientType}", tempBytes).Wait();
			}
			_UpFileInfo = new UpFileInfo() { PackNum = PackCount, Size = upbytes.Length, Version = vu.VersionCode };

			return true;
			//_UpFileInfo.PackNum = PackCount;
			//_UpFileInfo.Size = upbytes.Length;
			//_UpFileInfo.Version = vu.VersionCode;
		}

		public byte[] GetPackData(string version, int index, string productVersionId,int clientType)
		{
			logger.Info($"upgrade:{version}:{productVersionId}:{clientType}");
			return cache.LIndex<byte[]>($"upgrade:{version}:{productVersionId}:{clientType}", index);
		}

		public long GetPackCount(string version, string productVersionId, int clientType)
		{
			return cache.LLen($"upgrade:{version}:{productVersionId}:{clientType}");
		}

		public async Task WriteVersionAsync(int clientType, string productVersionId,string msg)
		{
			if (!Directory.Exists("version"))
			{
				Directory.CreateDirectory("version");
			}
			string filePath = $"version/{clientType}_{productVersionId}_version.log";
			using StreamWriter sw = File.CreateText(filePath);
			await sw.WriteLineAsync(msg);
			sw.Close();
		}
		public async Task<VersionUpgrade> GetVersionAsync(int clientType, string productVersionId)
		{
			string filePath = $"version/{clientType}_{productVersionId}_version.log";
			if (!File.Exists(filePath))
			{
				logger.Info($"{filePath} 不存在");
				return null;
			}
			var json = await File.ReadAllTextAsync(filePath);
			try
			{
				var vu = JsonConvert.DeserializeObject<VersionUpgrade>(json);
				return vu;
			}
			catch (Exception)
			{

				return null;
			}
		}
		public class VersionUpgrade
		{
			/// <summary>
			/// 版本号，唯一
			/// </summary>
			public string VersionCode { get; set; }

			public Guid ProductId { get; set; }
			public Guid ProductVersionId { get; set; }
			/// <summary>
			/// 客户端类型，0=控制器，1=沙盘，2=pad
			/// </summary>
			public int ClientType { get; set; }
			public string AppId { get; set; }
			/// <summary>
			/// 是否强制升级,0=不强制，1=强制
			/// </summary>
			public int ForceUpgrade { get; set; }
			/// <summary>
			/// 升级文件url
			/// </summary>
			public string FileUrl { get; set; }
			/// <summary>
			/// 升级提示信息
			/// </summary>
			public string UpgradeMessage { get; set; }

		}

		public class UpFileInfo
		{
			public string Version { get; set; }
			public int Size { get; set; }
			public int PackNum { get; set; }
		}

	}
}
